package websocket

import (
	"encoding/json"
	"fmt"

	"gitee.com/sweetsunnyflower/carpooling-server-go/pkg/logger"
	pkgwebsocket "gitee.com/sweetsunnyflower/carpooling-server-go/pkg/websocket"
	"github.com/golang-jwt/jwt/v5"
	"github.com/spf13/cast"

	"github.com/gofiber/contrib/websocket"
	"github.com/gofiber/fiber/v2"
)

type Controller struct {
	Token  string
	UserId uint64
}

type Data struct {
	Action  string                 `json:"action"`
	Payload map[string]interface{} `json:"payload"`
}

func (controller *Controller) Connect(conn *websocket.Conn) {
	// 获取token
	token := controller.GetToken()
	// 解析token
	fmt.Println(token)
	// 获取userId

	if old, ok := pkgwebsocket.OnlienUsers[controller.UserId]; ok {
		// 将原来的连接断开
		logger.InfoString("websocket close", "close", cast.ToString(controller.UserId))
		closeNormalClosure := websocket.FormatCloseMessage(websocket.CloseNormalClosure, "login")
		if err := old.WriteMessage(websocket.CloseMessage, closeNormalClosure); err != nil {
			fmt.Println(err)
		}
	}
	// 映射关系
	pkgwebsocket.OnlienUsers[controller.UserId] = conn
	pkgwebsocket.OnlienUsersConn[conn] = controller.UserId
}

func (controller *Controller) GetUserId() uint64 {
	return controller.UserId
}

func (controller *Controller) SetUserId(c *websocket.Conn) *Controller {
	user := c.Locals("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	userId := cast.ToUint64(claims["user_id"].(string))
	controller.UserId = userId
	return controller
}

func (controller *Controller) GetToken() string {
	return controller.Token
}

func (controller *Controller) SetToken(token string) *Controller {
	controller.Token = token
	return controller
}

func (controller *Controller) Disconnect(c *websocket.Conn) {
	delete(pkgwebsocket.OnlienUsersConn, c)
	logger.WarnString("websocket disconnect", "connect disconnect", cast.ToString(controller.UserId))
}

func (controller *Controller) GetOnlineUsers() map[uint64]*websocket.Conn {
	return pkgwebsocket.OnlienUsers
}

func (controller *Controller) Test(c *websocket.Conn, payload map[string]interface{}) bool {

	// 发送普通消息
	for _, c := range controller.GetOnlineUsers() {
		if err := c.WriteMessage(1, []byte("hello world")); err != nil {
			logger.ErrorString("websocket controller", "test", err.Error())
			break
		}
	}

	return true
}

func (controller *Controller) Error(c *websocket.Conn, payload map[string]interface{}) bool {
	data, _ := json.Marshal(&Data{"route_error", fiber.Map{}})
	if err := c.WriteMessage(websocket.TextMessage, data); err != nil {
		logger.ErrorString("websocket controller", "Error", err.Error())
	}

	return true
}

func (controller *Controller) Ping(c *websocket.Conn, payload map[string]interface{}) bool {
	data, _ := json.Marshal(&Data{"pong", fiber.Map{}})
	if err := c.WriteMessage(websocket.TextMessage, data); err != nil {
		logger.ErrorString("websocket controller", "Error", err.Error())
	}

	return true
}

func (controller *Controller) ClientConnect(c *websocket.Conn, payload map[string]interface{}) bool {
	data, _ := json.Marshal(&Data{"connect success", fiber.Map{}})
	if err := c.WriteMessage(websocket.TextMessage, data); err != nil {
		logger.ErrorString("websocket controller", "Error", err.Error())
	}

	return true
}
